package com.arpa.ntocc.common.service.impl;

import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.json.JSONUtil;
import com.arpa.core.utils.text.HashUtil;
import com.arpa.ntocc.common.common.cache.RoleCacheDO;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.dto.ShipmentAuthorizationJsonBean;
import com.arpa.ntocc.common.domain.dto.UserLoginCreateDTO;
import com.arpa.ntocc.common.domain.dto.UserLoginSearchDTO;
import com.arpa.ntocc.common.domain.dto.WarehouseAuthorizationJsonBean;
import com.arpa.ntocc.common.domain.entity.PartyRole;
import com.arpa.ntocc.common.domain.entity.UserLogin;
import com.arpa.ntocc.common.domain.vo.UserLoginVO;
import com.arpa.ntocc.common.mapper.UserLoginMapper;
import com.arpa.ntocc.common.service.IPartyRoleService;
import com.arpa.ntocc.common.service.IUserLoginService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.codec.Hex;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 登录账号表 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2019-08-02
 */
@Service
public class UserLoginServiceImpl extends ServiceImpl<UserLoginMapper, UserLogin> implements IUserLoginService {
    /**
     * 默认密码
     */
    private static final String DEFAULT_P = "abcd1234";


    private final IPartyRoleService partyRoleService;

    public UserLoginServiceImpl(IPartyRoleService partyRoleService) {
        this.partyRoleService = partyRoleService;
    }


    @Override
    public UserLogin getUserLoginByUserLoginId(String userLoginId) {
        return baseMapper.selectOne(new QueryWrapper<UserLogin>().lambda().eq(UserLogin::getUserLoginId, userLoginId));
    }

    /**
     * 登录账号列表
     * <p>
     * 1、用于后台账号管理列表
     *
     * @param searchDTO
     * @return
     * @author 刘秀荣
     */
    @Override
    public List<UserLoginVO> queryList(UserLoginSearchDTO searchDTO) {

        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StringUtils.isNotEmpty(searchDTO.getSortField())) {
            searchDTO.setSortField(CommonUtil.camel2Underline(searchDTO.getSortField()));
        }
        List<UserLoginVO> userLoginVOList = baseMapper.queryList(searchDTO);

        //查询用户角色表
        userLoginVOList.forEach(userLoginVO -> {
            List<RoleCacheDO> roleList = partyRoleService.listRoles(userLoginVO.getPartyCode());
            userLoginVO.setRoleList(roleList);
        });

        return userLoginVOList;


    }

    /**
     * 登录账号列表,包含总数
     *
     * @param searchDTO
     * @return
     */
    @Override
    public UserLoginVO queryListSum(UserLoginSearchDTO searchDTO) {
        return baseMapper.queryListSum(searchDTO);
    }


    /**
     * 保存登录账号，保存用户角色
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(UserLoginCreateDTO entity) {

        int count = baseMapper.selectCount(new QueryWrapper<UserLogin>().lambda().eq(UserLogin::getUserLoginId, entity.getUserLoginId()));
        if (count > 0) {
            throw new ServiceException("账号已存在");
        }

        UserLogin userLogin = new UserLogin();
        userLogin.setUserLoginId(entity.getUserLoginId());
        userLogin.setPartyCode(entity.getPartyCode());
        userLogin.setCreatedBy(UserUtil.getCode());
        userLogin.setModifiedBy(UserUtil.getCode());
        userLogin.setUserLoginType(entity.getUserLoginType());
        if (IterUtil.isNotEmpty(entity.getShipmentAuthorization())) {
            userLogin.setShipmentAuthorization(JSONUtil.toJsonStr(entity.getShipmentAuthorization()));
        }
        if (IterUtil.isNotEmpty(entity.getWarehouseAuthorization())) {
            userLogin.setWarehouseAuthorization(JSONUtil.toJsonStr(entity.getWarehouseAuthorization()));
        }
        String salt = Hex.encodeToString(HashUtil.generateSalt(8));
        String hashPassword = SmUtil.sm3(DEFAULT_P + salt);
        userLogin.setCurrentPassword(hashPassword);
        userLogin.setSalt(salt);
        baseMapper.insert(userLogin);


        //保存角色信息
        return this.partyRoleService.save(entity.getPartyCode(), entity.getRoleCodeList());
    }

    /**
     * 修改登录账号信息
     *
     * @param entity
     * @return
     */
    @Override
    public boolean update(UserLoginCreateDTO entity) {

        UserLogin userLogin = getUserLoginByUserLoginId(entity.getUserLoginId());
        if (null == userLogin) {
            throw new ServiceException("账号不存在");
        }
        userLogin.setUserLoginType(entity.getUserLoginType());
        if (IterUtil.isNotEmpty(entity.getShipmentAuthorization())) {
            userLogin.setShipmentAuthorization(JSONUtil.toJsonStr(entity.getShipmentAuthorization()));
        }
        if (IterUtil.isNotEmpty(entity.getWarehouseAuthorization())) {
            userLogin.setWarehouseAuthorization(JSONUtil.toJsonStr(entity.getWarehouseAuthorization()));
        }
        super.updateById(userLogin);
        return this.partyRoleService.save(entity.getPartyCode(), entity.getRoleCodeList());
    }

    /**
     * 批量删除登录账号及角色
     *
     * @param codes
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchRemove(List<String> codes) {
        List<UserLogin> userLoginList = baseMapper.selectList(new QueryWrapper<UserLogin>().lambda().in(UserLogin::getPartyCode, codes));
        if (CollectionUtils.isEmpty(userLoginList)) {
            throw new ServiceException("没有查询到要删除的账号");
        }
        //删除用户
        baseMapper.delete(new QueryWrapper<UserLogin>().lambda().in(UserLogin::getPartyCode, codes));
        //删除用户角色
        partyRoleService.remove(new QueryWrapper<PartyRole>().lambda().in(PartyRole::getPartyCode, codes));
    }

    /**
     * 删除登录账号
     * @param userLoginId 账号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByUserLoginId(String userLoginId) {
        partyRoleService.removeByUserLoginId(userLoginId);
        baseMapper.delete(new LambdaQueryWrapper<UserLogin>().eq(UserLogin::getUserLoginId, userLoginId));
    }
    /**
     * 获取登录账号信息
     *
     * @param userLoginId
     * @return
     */
    @Override
    public UserLoginVO getByUserLoginId(String userLoginId) {
        UserLoginVO vo = baseMapper.getByUserLoginId(userLoginId);
        if (null == vo) {
            throw new ServiceException("账号不存在");
        }

        if (StrUtil.isNotBlank(vo.getWarehouseAuthorization())) {
            List<WarehouseAuthorizationJsonBean> warehouseAuthorizationJsonBeans = JSONUtil.toList(JSONUtil.parseArray(vo.getWarehouseAuthorization()), WarehouseAuthorizationJsonBean.class);
            if (IterUtil.isNotEmpty(warehouseAuthorizationJsonBeans)) {
                vo.setWarehouseAuthorizations(warehouseAuthorizationJsonBeans);
            }
        }
        if (StrUtil.isNotBlank(vo.getShipmentAuthorization())) {
            List<ShipmentAuthorizationJsonBean> shipmentAuthorizationJsonBeans = JSONUtil.toList(JSONUtil.parseArray(vo.getShipmentAuthorization()), ShipmentAuthorizationJsonBean.class);
            if (IterUtil.isNotEmpty(shipmentAuthorizationJsonBeans)) {
                vo.setShipmentAuthorizations(shipmentAuthorizationJsonBeans);
            }
        }
        //查询用户角色表
        List<PartyRole> partyRoleList = partyRoleService.list(new QueryWrapper<PartyRole>().lambda().eq(PartyRole::getPartyCode, vo.getPartyCode()));
        //set用户角色信息
        if (IterUtil.isNotEmpty(partyRoleList)) {
            List<String> roleCodeList = partyRoleList.stream()
                    .filter(partyRole -> partyRole.getPartyCode().equals(vo.getPartyCode()))
                    .map(PartyRole::getRoleCode).collect(Collectors.toList());
            vo.setRoleCodeList(roleCodeList);
        } else {
            vo.setRoleCodeList(new ArrayList<String>());
        }
        return vo;
    }

    /**
     * 获取用户登录选择的仓库信息
     *
     * @param authorizeDataCode 登录选择的仓库标识
     * @return
     */
    @Override
    public Map<String, Object> getLoginChooseWarehouseInfo(String authorizeDataCode) {
        return baseMapper.getLoginChooseWarehouseInfo(authorizeDataCode);
    }

    /**
     * 获取用户登录选择的货主信息
     *
     * @param authorizeDataCode 登录选择的货主标识
     * @return
     */
    @Override
    public Map<String, Object> getLoginChooseShipmentInfo(String authorizeDataCode) {
        return baseMapper.getLoginChooseShipmentInfo(authorizeDataCode);
    }

    /**
     * 获取授权给用户的仓库列表
     *
     * @param warehouseCodes
     * @return
     */
    @Override
    public List<Map<String, Object>> getUserloginWarehouse(List<String> warehouseCodes) {
        return baseMapper.getUserloginWarehouse(warehouseCodes);
    }

    /**
     * 获取授权给用户的货主列表
     *
     * @param shipmentCodes
     * @return
     */
    @Override
    public List<Map<String, Object>> getUserloginShipment(List<String> shipmentCodes) {
        return baseMapper.getUserloginShipment(shipmentCodes);
    }
}
